In a digital signal processor implementation of some complex functions, it is common to utilize basic building blocks or code segments which may be interconnected in multiple ways. These code segments are analogous to separate hardware modules which might previously have been found in various systems employing patch chords or switchable hardwired interconnections to permit selection and configuration of the modules.
As but one example, although the invention is not intended to be so limited and admits to numerous embodiments and applications, in the implementation of a music synthesizer with a digital signal processor, such modules might include analogous software implementations of hardware modules such as oscillators, filters, or voltage controlled amplifiers. These modules were found in music synthesizers of the 1970s wherein they were interconnected as desired and as previously described with patch chords or other means.
In a DSP implementation of such complex functions, in many applications it may be desirable to reconfigure the system in real time. Again, using the musical application as but one example, it may be desirable to provide a DSP implementation of a music synthesizer wherein the synthesizer may be capable of being reconfigured in real time to permit generation of several different sounds at the same time. Such capability being referred to in the art as "polytimbral".
In such an implementation of function wherein real time reconfiguration is required (typically in DSP systems and code, although the invention is not so limited), one apparent solution to the problem of real time configuration is to group together all the possible code segments needed to implement a function such as the particular sound of one instrument, a filter, or the like. Each code sequence necessary to implement that function is made a "callable" routine. In this manner, a given configuration then need only be a list of such subroutines and the order in which they appear. It would appear by such an implementation, that this approach would allow for great flexibility in the configuration of the modules. However, it was found in the art that in fact such implementations suffered significant performance penalties resulting from the time involved to effect the necessary calls and returns made to each such code segment.
In the development of the art, a solution eventually appeared wherein the required code modules could be linked together as needed. This linking was a common programming procedure employed by program compilers, for example, which typically would collect multiple code segments together into a single code sequence.
One problem with this approach, however, relates to the particular application being discussed wherein various code modules in need of execution are changing over time, as is the case, for example, when a DSP, in order to implement a polytimbral combination of brass and woodwind sounds, for example, would be required to first implement the brass code module followed very quickly by that of the woodwind in order for the sound to be perceived as a simultaneous voicing of both instrument types. Moreover, the problem is compounded in certain applications due to the nature of shared memory DSP co-processor systems which may have a relatively small amount of shared memory on the order of 8K, for example, which must execute code resident therein at a very rapid rate. Due to the small memory size, in order to achieve the desired multi-timbral and other effects, it is necessary to periodically load other code from the host into this shared memory for execution by the DSP. However, due to the additional factor of this code having to execute very rapidly (for example to generate satisfying synthesized acoustic sound), the problem arose of how to interject such additional code modules into this limited memory in such a way so as to avoid the host attempting to update the buffer of such a shared memory while code in the buffer was being executed by the DSP.
Usually, the DSP is disabled during these periods when the host is writing additional DSP program modules to the shared memory so as to prevent the DSP from attempting to execute such instructions which have only partially been written out by the host processor to the shared memory. A "ping-pong" form of double buffering has long been known in the data processing arts wherein one buffer contains code being executed while a second buffer is being filled. The situation is then reversed wherein the code in the just-filled buffer executes while additional code is being loaded into the first buffer. However, this conventional practice, while useful in preventing the host from updating the buffer being executed by the DSP in some instances, is not entirely satisfactory. For example, if the host attempted to update buffers twice in rapid succession such a double buffering technique would not prevent the undesired updating by the host of the buffer being executed by the DSP.
Accordingly, for these and other reasons, a system and method were long desired for dynamically linking code segments wherein executable code is optimized by performing linking of code segments in real time.